package com.airoc.demo.utils;

import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

/**
 * 定义全局的json日期转换器
 */
public class JsonObjectConverterMapper extends ObjectMapper {

	private static final long serialVersionUID = 5894193923382279897L;
	private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
	private ThreadLocal<SimpleDateFormat> localSdf = new ThreadLocal<SimpleDateFormat>() {
		@Override
		protected SimpleDateFormat initialValue() {
			return null;
		}
	};
	
	private ThreadLocal<String> DATE_PATTERN = new ThreadLocal<String>() {
		@Override
		protected String initialValue() {
			return DEFAULT_DATE_FORMAT;
		}
	};
	public SimpleDateFormat getDateFormat() {
		SimpleDateFormat df = (SimpleDateFormat) localSdf.get();
		this.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
			@Override
			public Object findSerializer(Annotated a) {
				if (a instanceof AnnotatedMethod) {
					AnnotatedElement m = a.getAnnotated();
					DateTimeFormat an = m.getAnnotation(DateTimeFormat.class);
					if (an != null) {
						if (!DEFAULT_DATE_FORMAT.equals(an.pattern())) {
							DATE_PATTERN.set(an.pattern());
							return new JsonDateSerializer(an.pattern());
						}
					}
				}
				return super.findSerializer(a);
			}
		});
		if (df == null) {
			if(DATE_PATTERN.get()!=null) {
				df = new SimpleDateFormat(DATE_PATTERN.get());
			}else
				df = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
			localSdf.set(df);
		}
		return localSdf.get();
	}

	public JsonObjectConverterMapper() {
		// 设置null值不参与序列化(字段不被显示)
		// this.setSerializationInclusion(Include.NON_NULL);
		// 禁用空对象转换json校验
		this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		this.setDateFormat(getDateFormat());
	}

	public static class JsonDateSerializer extends JsonSerializer<Date> {
		private SimpleDateFormat dateFormat;

		public JsonDateSerializer(String format) {
			dateFormat = new SimpleDateFormat(format);
		}

		@Override
		public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
				throws IOException, JsonProcessingException {
			String value = dateFormat.format(date);
			gen.writeString(value);
		}
	}
}

